import java.util.Iterator;
import java.util.List;


public class Player {
	public enum Status {
	    Active, Archived, Inactive
	}
	
	private Hand hand;
	private int coins;
	private Status status;
	private int noWinning;
	private IPlayerStrategy playerStrategy;
	private Deck deck;
	private String name;
	
	private List<Integer> tempValue;
	private boolean valueUpdated;
	
	/**
	 * Create player, initial status of player is Status.Active
	 * @param playerStrategy - in most cases HumanStrategy or BotStrategy
	 * @param deck - deck, place from player can take cards
	 * @param coins - starting no of coins
	 */
	public Player(IPlayerStrategy playerStrategy, String name, Deck deck, int coins)
	{
		this.playerStrategy = playerStrategy;
		this.deck = deck;
		this.coins = coins;
		this.name = name;
		this.noWinning = 0;
		this.status = Status.Active;
		this.valueUpdated = false;
		hand = new Hand();
	}
	
	/**
	 * Gets name of player
	 * @return name of player
	 */
	public String getName()
	{
		return name;
	}
	
	/**
	 * Sets status of player
	 * @param status status to set
	 */
	public void setStatus(Status status)
	{
		this.status = status;
	}
	
	/**
	 * Return current status of player
	 * @return status of player
	 */
	public Status getStatus()
	{
		return status;
	}
	
	/**
	 * Returns current no. of coins
	 * @return number of coins
	 */
	public int getCoins()
	{
		return coins;
	}
	
	/**
	 * Takes coins from player
	 * @param noCoins number of taken coins
	 */
	public void takeCoins(int noCoins)
	{
		if(noCoins > coins)
		{
			//TODO Rzuć coś sensownego
		}
		coins -= noCoins;
	}
	
	/**
	 * Gives coins to player
	 * @param noCoins number of coins to give 
	 */
	public void giveCoins(int noCoins)
	{
		coins += noCoins;
	}
	
	/**
	 * Fills hand of player with cards from deck
	 */
	public void fillHand()
	{
		for(int i = 0; i < hand.getNumberOfNeededCards(); i++) {
			hand.giveCard(deck.takeCard());
		}
		playerStrategy.giveCards(hand.showCards());
		valueUpdated = false;
	}
	
	/**
	 * Exchange cards in hand with the deck
	 */
	public void exchangeCards()
	{
		List<Card> cardsToExchange = playerStrategy.getCardsToExchange(hand.getMinNumberOfCardsToExchange(), hand.getMaxNumberOfCardsToExchange());
		
		if(hand.getMaxNumberOfCardsToExchange() < cardsToExchange.size()) {
			throw new TablePlayerIncorrectImplementation("Some player wants to exchange too many cards");
		}
		
		Iterator<Card> iterC = cardsToExchange.iterator();
		while(iterC.hasNext()) {
			hand.takeCard(iterC.next());
			hand.giveCard(deck.takeCard());
		}
		
		playerStrategy.giveCards(hand.showCards());
		valueUpdated = false;
	}
	
	/**
	 * Return value of hand
	 * @return value of hand
	 */
	public List<Integer> getValue()
	{
		if(!valueUpdated) {
			tempValue = hand.getValue();
			valueUpdated = true;
		}
		return tempValue;
	}
	
	/**
	 * Returns a wanted bet by the player
	 * @return no. of coins in the bet
	 */
	public int sendBet()
	{
		return playerStrategy.sendBet();
	}
}
